require 'fox16'
require 'mechanize'
require 'iconv'

include Fox
include Net

=begin
orange sms sender gui 
created by giu (http://giu.me) with fxruby
mechanize-part (login and sms-sending) by mirko stocker (http://blog.misto.ch/archives/606)

lizenz:
----------------------------------------------------------------------------
Die "CHEESBURGER ODER BEER-WARE" LIZENZ (Revision 42):
<giuseppe@giu.me> schrieb diese Datei (mit der Hilfe von <me@misto.ch>). Solange Sie diesen Vermerk nicht entfernen,
koennen Sie mit der Datei machen, was Sie moechten. Wenn wir uns eines Tages treffen
und Sie denken, die Datei ist es wert, koennen Sie mir (giu) dafuer einen Cheesburger bei MC Donald's ausgeben. Falls Sie Mirko treffen sollten,
koennen Sie Ihm natuerlich ein Bier ausgeben.
----------------------------------------------------------------------------

=end

class OrangeSMSSender < FXMainWindow

  NUMBER_OF_COLS= 30
  NUMBER_OF_ROWS= 2  
  MAX_NUMBER_OF_CHARS= 144
	WINDOW_HEIGHT= 580
	WINDOW_WIDTH= 300
	COLOR_RED= FXRGB(255,0,0) #FXColor::Red mag man nicht hier
	COLOR_GREEN= FXRGB(0,142,37) #FXColor::Green mag man natuerlich auch nicht
	BOLD_FONT= "Arial,80,bold"
	#settings fuer's nachrichten-feld
	NORMAL_FONT_FACE= "Arial"
	NORMAL_FONT_SIZE= 8
  
  def initialize(app)
    super(app, "Orange SMS Sender", :width => WINDOW_WIDTH, :height => WINDOW_HEIGHT)

    #titel
    information_vframe= FXVerticalFrame.new(self)
    FXLabel.new(information_vframe, "orange sms sender v0.2", :opts => JUSTIFY_LEFT){|labelSetting|
      labelSetting.font= FXFont.new(app, "Arial,200")
    }
		link_label= FXLabel.new(information_vframe, "by giu 2008 (http://www.giu.me)", :opts => JUSTIFY_LEFT)
    
		#login-angaben
    user_credentials_group= FXGroupBox.new(self, "login-angaben", :opts => GROUPBOX_TITLE_LEFT|FRAME_RIDGE|LAYOUT_FILL_X)
    user_information_hframe= FXHorizontalFrame.new(user_credentials_group)
    
    user_information= FXMatrix.new(user_information_hframe, NUMBER_OF_ROWS, :opts => LAYOUT_FILL|MATRIX_BY_ROWS)
    FXLabel.new(user_information, "username: ")
    FXLabel.new(user_information, "password: ")
    username= FXTextField.new(user_information, NUMBER_OF_COLS)
    password= FXTextField.new(user_information, NUMBER_OF_COLS){|pw|
      pw.textStyle= TEXTFIELD_PASSWD
    }
    
    #nachricht-informationen
    message_group= FXGroupBox.new(self, "nachricht-informationen", :opts => GROUPBOX_TITLE_LEFT|FRAME_RIDGE|LAYOUT_FILL_X, :width=>500, :height=>300)
    message_vframe = FXVerticalFrame.new(message_group, :opts => LAYOUT_FILL_X)
      
			FXLabel.new(message_vframe, "mehrere handy-nr mit semikolon (;) trennen\n(maximal 10 empfaenger erlaubt)", :opts => JUSTIFY_LEFT )
			
      number_hframe= FXHorizontalFrame.new(message_vframe)
      FXLabel.new(number_hframe, "handy-nr: ")
      number= FXTextField.new(number_hframe, NUMBER_OF_COLS)
			
      counter_hframe= FXHorizontalFrame.new(message_vframe)
      FXLabel.new(counter_hframe, "nachricht: (anzahl verfuegbarer zeichen:")
      counter_label= FXLabel.new(counter_hframe, "#{MAX_NUMBER_OF_CHARS})")   

    message= FXText.new(message_vframe, :height => 150, :opts => LAYOUT_FILL_X|LAYOUT_FIX_HEIGHT){|textSetting|
			textSetting.font= FXFont.new(app, NORMAL_FONT_FACE, NORMAL_FONT_SIZE, :encoding => FXFont::FONTENCODING_ISO_8859_1)
		}
		
		
    send_button= FXButton.new(self, "nachricht senden")
    
    #informationen ueber den versand-status
    message_sending_vframe= FXVerticalFrame.new(self)
    error_label= FXLabel.new(message_sending_vframe, nil, :opts => JUSTIFY_LEFT){|labelSetting|
			labelSetting.font= FXFont.new(app, BOLD_FONT)
			labelSetting.textColor= COLOR_RED
    }
    message_sending_label= FXLabel.new(message_sending_vframe, nil)
    logged_in_label= FXLabel.new(message_sending_vframe, nil)
    message_sent_label= FXLabel.new(message_sending_vframe, nil){|labelSetting|
      labelSetting.font= FXFont.new(app, BOLD_FONT)
			labelSetting.textColor= COLOR_GREEN
		}
		
		#--------------------------
    
    #anzeige der anzahl verfuegbaren zeichen 
    message.connect(SEL_CHANGED){
      #orange.ch zaehlt fuer newlines 2 zeichen ab, FXText nur 1 zeichen
      number_of_newlines= message.text().count("\n")
			@number_of_remaining_chars= MAX_NUMBER_OF_CHARS - message.text().size - number_of_newlines
      counter_label.text = @number_of_remaining_chars.to_s+ ")"
    }
    
    #einloggen und nachricht versenden
    #sms-sender code by mirko stocker (http://blog.misto.ch)
    send_button.connect(SEL_COMMAND){
      message_sending_label.text = logged_in_label.text = message_sent_label.text = error_label.text = ""
      
			#anzahl empfaenger ermitteln
		  number_of_recipients= number.text.split(/;/).size
      begin
      if !username.text.empty? and !password.text.empty? and !number.text.empty? and number_of_recipients <= 10 and (@number_of_remaining_chars >= 0 and @number_of_remaining_chars != MAX_NUMBER_OF_CHARS) then 
        message_sending_label.text= "verbinde mit orange.ch, login..."
        WWW::Mechanize.new do |agent|
					#einloggen
					Timeout::timeout(5) do 
						agent.get('https://www.orange.ch/footer/login') do |page|
							find_form_with_field(page, 'username') do |f|
								f.username = username.text
								f.password = password.text
								f.submit
							end
						end
					end
					
					#nachricht versenden
					Timeout::timeout(5) do
						agent.get('https://www.orange.ch/myorange/sms') do |page|
							find_form_with_field(page, 'messageInput') do |f|
								f.destinationNumberInput = number
								f.messageInput = Iconv.conv("ISO-8859-1", "UTF-8", message.text)
								f.wui_target_id = 'sendButton'
								f.wui_event_id = 'onclick'
								f.submit
							end
						end
					end
					logged_in_label.text= "> login erfolgreich"
					message_sent_label.text= "> nachricht wurde versendet"
				end
				else
					error_label.text= "fehler: nachricht wurde nicht versendet\nbitte eingaben ueberpruefen"
					if(number_of_recipients > 10) then
						error_label.text+= "=> zu viele empfaenger eingegeben"
					end
				end
			
			rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
				message_sending_label.text = logged_in_label.text = message_sent_label.text = error_label.text = ""
				if(e.instance_of? Timeout::Error) then
					error_label.text= "fehler: orange.ch scheint unerreichbar\nzu sein! bitte versuchen sie es erneut!"
				else
					error_label.text= "fehler: login koennte falsch sein!"
				end
			end
				
    }
              
  end
  
  def create
    super
    show(PLACEMENT_SCREEN)
  end
  
  # formular finden, welches das feld mit dem namen fieldname enthaelt (method by mirko stocker)
  def find_form_with_field(page, fieldname)
    page.forms.each do |form|
      if form.fields.find{|f| f.name == fieldname}
        yield form
      end
    end
  end
end

if __FILE__ == $0
  FXApp.new do |app|
    OrangeSMSSender.new(app)
    app.create
    app.run
  end
end

